//SPDX-FileCopyrightText: Copyright 2025-2025 深圳市同心圆网络有限公司
//SPDX-License-Identifier: GPL-3.0-only

package atomgit_triger

import (
	"fmt"
	"io"
	"time"

	"atomgit.com/openlinksaas-org/api-server/triger_impl/core"
	"atomgit.com/openlinksaas-org/proto-gen-go.git/project_triger_api"
	"github.com/gin-gonic/gin"
	"go.uber.org/zap"
)

const _RUNNER_NAME = "atomgit"

type AtomGitTrigerRunner struct {
	queryHandler core.QueryTrigerInfoHandler
	msgHandler   core.TrigerMsgHandler
	logger       *zap.Logger
}

func NewAtomGitTrigerRunner() core.TrigerRunner {
	return &AtomGitTrigerRunner{}
}

func (tr *AtomGitTrigerRunner) Init(group *gin.RouterGroup, queryHandler core.QueryTrigerInfoHandler, msgHandler core.TrigerMsgHandler, logger *zap.Logger) {
	tr.queryHandler = queryHandler
	tr.msgHandler = msgHandler
	tr.logger = logger

	runnerUrl := fmt.Sprintf("/%s/:id", _RUNNER_NAME)
	group.POST(runnerUrl, func(c *gin.Context) {
		id := c.Param("id")
		cfg, ok := tr.queryHandler(c.Request.Context(), _RUNNER_NAME, id)
		if !ok {
			c.Status(404)
			return
		}
		tr.dispatch(c, cfg)
	})
}

func (tr *AtomGitTrigerRunner) GetTypeInfo() *project_triger_api.TrigerTypeInfo {
	return &project_triger_api.TrigerTypeInfo{
		TypeId:            _RUNNER_NAME,
		TypeDesc:          "接收来自atomgit的webhook调用",
		HasSecret:         true,
		AttrDescGroupList: core.GitAttrDescGroupList,
	}
}

func (tr *AtomGitTrigerRunner) dispatch(c *gin.Context, trigerCfg *core.TrigerConfigInfo) {
	evType := c.GetHeader("X-AtomGit-Event")
	evId := c.GetHeader("X-AtomGit-Delivery")

	if evId == "" {
		c.String(403, "not atomgit webhook request")
		return
	}
	//TODO check request token
	reqData, err := io.ReadAll(c.Request.Body)
	if err != nil {
		c.String(503, err.Error())
		return
	}

	nowTime := time.Now()

	attrList := []string{
		fmt.Sprintf("%s=%s", core.COMMON_TRIGER_TYPE, _RUNNER_NAME),
		fmt.Sprintf("%s=%s", core.COMMON_TRIGER_ID, trigerCfg.TrigerId),
		fmt.Sprintf("%s=%s", core.COMMON_TRIGER_TIME_AT, nowTime.Format(time.RFC3339)),
	}
	if evType == "push" {
		newAttrList, err := ExtractPushHookAttr(reqData)
		if err != nil {
			c.String(503, err.Error())
			return
		}
		attrList = append(attrList, newAttrList...)
	} else if evType == "tag_push" {
		newAttrList, err := ExtractTagHookAttr(reqData)
		if err != nil {
			c.String(503, err.Error())
			return
		}
		attrList = append(attrList, newAttrList...)
	} else if evType == "issues" {
		newAttrList, err := ExtractIssueHookAttr(reqData)
		if err != nil {
			c.String(503, err.Error())
			return
		}
		attrList = append(attrList, newAttrList...)
	} else if evType == "issue_comment" {
		newAttrList, err := ExtractNoteHookAttr(reqData)
		if err != nil {
			c.String(503, err.Error())
			return
		}
		attrList = append(attrList, newAttrList...)
	} else if evType == "pull_requests" {
		newAttrList, err := ExtractPrHookAttr(reqData)
		if err != nil {
			c.String(503, err.Error())
			return
		}
		attrList = append(attrList, newAttrList...)
	} else {
		c.Status(200)
		return
	}

	err = tr.msgHandler(c.Request.Context(), trigerCfg.ProjectId, &project_triger_api.TrigerMsgInfo{
		MsgId:     evId,
		TrigerId:  trigerCfg.TrigerId,
		TimeStamp: nowTime.UnixMilli(),
		AttrList:  attrList,
		Content:   reqData,
	}, tr.logger)
	if err != nil {
		c.String(503, err.Error())
		return
	}
	c.Status(200)
}
